package com.fingard.dsp.bank.directbank.allinpay02;

import com.alibaba.fastjson.JSONObject;
import com.fingard.constant.Format;
import com.fingard.dsp.bank.directConfig.ActSetItem;
import com.fingard.dsp.bank.directbank.FailCode;
import com.fingard.dsp.bank.directbank.PaymentState;
import com.fingard.dsp.bank.directbank.allinpay02.util.SybUtil;
import com.fingard.dsp.bank.directbank.bankInterface.ISinglePay;
import com.fingard.dsp.bank.reqrespobj.batpayrec.ReqBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.RetAtsBatPayRec;
import com.fingard.dsp.bank.reqrespobj.single.*;
import com.fingard.dsp.bank.reqrespobj.single.detail.RetAtsSglDetail;
import com.fingard.net.ConnState;
import com.fingard.text.StringHelper;
import com.fingard.xml.XElement;
import com.fingard.xml.XmlTextReader;
import com.fingard.xml.XmlTextWriter;

import java.util.HashMap;
import java.util.TreeMap;

public class AllInPay02SinglePay extends AllInPay02Base implements ISinglePay {
    @Override
    public RetAtsSingle d_1908_SglPay(ReqSingle p_req1908) throws Exception {
        RetAtsSingle retAts = new RetAtsSingle(p_req1908.reqHeader);

        RetAtsSglDetail tmpRetDetail = new RetAtsSglDetail(p_req1908);
        boolean isConvertTo1988 = false;
        if ("6908".equals(p_req1908.reqHeader.transType) && "690802CNVRT".equals(p_req1908.reqHeader.commandCode)) {
            isConvertTo1988 = true;
        } else if ("190803".equals(p_req1908.reqHeader.commandCode)) {
            isConvertTo1988 = false;
        } else if ("2".equals(p_req1908.singleDetail.isPrivate) || "0".equals(p_req1908.singleDetail.isPrivate)) {
            isConvertTo1988 = true;
        }
        if (isConvertTo1988) {
            this.WriteBankLogLn("单笔对公转批量代付");
            ReqBatPayRec p_req1988 = new ReqBatPayRec(p_req1908);//单笔转批量
            AllInPay02BatPayRec tmpBatPay = new AllInPay02BatPayRec();
            tmpBatPay.setSbLog(this.sbLog);
            tmpBatPay.setLogFlushTime(this.logFlushTime);
            tmpBatPay.isFromSinglePay = true;
            tmpBatPay.reqHeader = p_req1988.reqHeader;
            tmpBatPay.bankFront = this.bankFront;
            RetAtsBatPayRec retAts1988 = tmpBatPay.d_1988_BatPay(p_req1988);
            tmpRetDetail = retAts1988.convertToSingle();
        } else if ("690803".equals(p_req1908.reqHeader.commandCode)) {
            tmpRetDetail = d_690803(p_req1908);
        } else if ("6908".equals(p_req1908.reqHeader.transType) || "190802".equals(p_req1908.reqHeader.commandCode)) {
            tmpRetDetail = d_190802(p_req1908);
        } else if ("1908JFB".equals(p_req1908.reqHeader.commandCode)) {
            tmpRetDetail = d_1908JFB(p_req1908);
        } else if ("190803".equals(p_req1908.reqHeader.commandCode)) {
            tmpRetDetail = d_190803(p_req1908);
        } else {
            tmpRetDetail.respInfo = "不支持的指令类型：" + p_req1908.reqHeader.transType + "-" + p_req1908.reqHeader.commandCode;
        }

        retAts.writeRetDetail(tmpRetDetail);
        return retAts;
    }

    private RetAtsSglDetail d_190802(ReqSingle p_req1908) throws Exception {
        RetAtsSglDetail tmpRetDetail = new RetAtsSglDetail(p_req1908);

        try {
            ActSetItem actItem = getBankConfig().getActSetItem(p_req1908.singleDetail.payAct, "");
            if (actItem == null) {
                tmpRetDetail.respCode = "0";
                tmpRetDetail.respInfo = "未找到账号[" + p_req1908.singleDetail.payAct + "]商户配置信息";
                tmpRetDetail.transState = PaymentState.FAIL_Payment;
                tmpRetDetail.payInfoCode = FailCode.E9981;
                return tmpRetDetail;
            }

            AllInPay02Header header = new AllInPay02Header();
            header.TRX_CODE = "100014";
            header.REQ_SN = p_req1908.singleDetail.askNumber;

            XmlTextWriter xmlWriter = new XmlTextWriter();
            writeRealTimeCommonHeader(xmlWriter, header, actItem);

            XElement tmpXElement = new XElement("TRANS", "");
            String BUSINESS_CODE = this.getBankConfig().getMapValueBySrcXE("BUSINESS_CODE_1908", "srcCode", "desCode", p_req1908.singleDetail.srcXElement, p_req1908.singleDetail.useType);
            if (StringHelper.isNullOrEmpty(BUSINESS_CODE)) {
                BUSINESS_CODE = this.getBankConfig().getMapValueBySrcXE("BUSINESS_CODE_1988", "srcCode", "desCode", p_req1908.singleDetail.srcXElement, p_req1908.singleDetail.useType);
            }
            tmpXElement.addChild(new XElement("BUSINESS_CODE", BUSINESS_CODE));
            tmpXElement.addChild(new XElement("MERCHANT_ID", actItem.merchantId));
            tmpXElement.addChild(new XElement("SUBMIT_TIME", Format.DateTime14Format.format(p_req1908.singleDetail.getPayDateTime())));

            String[] findValues = new String[2];
            findValues[0] = p_req1908.singleDetail.recBankCode;
            findValues[1] = p_req1908.singleDetail.recAreaName;
            HashMap<String, String> BANK_CODE = this.getBankConfig().getMapAdvanceValues("BankCodeMapping",
                    new String[]{"ATSBankCode", "ATSAreaName"}, new String[]{"value"}, findValues);
            if (BANK_CODE != null && BANK_CODE.size() > 0 && BANK_CODE.containsKey("value")) {
                tmpXElement.addChild(new XElement("BANK_CODE", BANK_CODE.get("value")));
            } else {
                tmpXElement.addChild(new XElement("BANK_CODE", findValues[0]));
            }

            if (p_req1908.singleDetail.cardType.equals("1")) {
                tmpXElement.addChild(new XElement("ACCOUNT_TYPE", "01"));
            } else if (p_req1908.singleDetail.cardType.equals("3")) {
                tmpXElement.addChild(new XElement("ACCOUNT_TYPE", "02"));
            } else {
                tmpXElement.addChild(new XElement("ACCOUNT_TYPE", "00"));
            }

            tmpXElement.addChild(new XElement("ACCOUNT_NO", p_req1908.singleDetail.recAct));
            tmpXElement.addChild(new XElement("ACCOUNT_NAME", p_req1908.singleDetail.recName));
            tmpXElement.addChild(new XElement("PROVINCE", p_req1908.singleDetail.getOppProvinceAndCity()[0]));
            tmpXElement.addChild(new XElement("CITY", p_req1908.singleDetail.getOppProvinceAndCity()[1]));

            if (p_req1908.singleDetail.isPrivate.equals("1")) {
                tmpXElement.addChild(new XElement("ACCOUNT_PROP", "0"));
            } else {
                tmpXElement.addChild(new XElement("ACCOUNT_PROP", "1"));
            }

            tmpXElement.addChild(new XElement("AMOUNT", StringHelper.amountMultiply100(p_req1908.singleDetail.payAmount)));
            tmpXElement.addChild(new XElement("CURRENCY", convertCurToBank(p_req1908.singleDetail.payCur)));
            tmpXElement.addChild(new XElement("ID_TYPE", convertCertTypeToBank(p_req1908.singleDetail.certType)));
            tmpXElement.addChild(new XElement("ID", p_req1908.singleDetail.certNum));

            if ("1".equals(p_req1908.singleDetail.isPrivate)) {
                tmpXElement.addChild(new XElement("UNION_BANK", ""));
            } else {
                tmpXElement.addChild(new XElement("UNION_BANK", p_req1908.singleDetail.cnapsCode));
            }
            tmpXElement.addChild(new XElement("SUMMARY", p_req1908.singleDetail.purpose));
            tmpXElement.addChild(new XElement("REMARK", p_req1908.singleDetail.memo));

            this.nodeAnalysis(p_req1908.singleDetail.srcXElement, tmpXElement, this.getCharset());

            xmlWriter.writeXElement(tmpXElement);
            xmlWriter.writeEndDocument();

            String[] tmpStrRet = sendToBank(xmlWriter.toXmlString(), actItem);

            if (tmpStrRet[0].length() == 0) {
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
                if (tmpBkReader != null) {
                    String INFO_RET_CODE = tmpBkReader.getFirstText("/AIPG/INFO/RET_CODE");
                    String INFO_ERR_MSG = tmpBkReader.getFirstText("/AIPG/INFO/ERR_MSG");
                    String tmpBkRET_CODE = tmpBkReader.getFirstText("/AIPG/TRANSRET/RET_CODE");
                    String tmpBkERR_MSG = tmpBkReader.getFirstText("/AIPG/TRANSRET/ERR_MSG");

                    if (p_req1908.singleDetail.askNumber.equals(tmpBkReader.getSimpleText("REQ_SN"))) {
                        tmpRetDetail.respCode = "0";
                        tmpRetDetail.reqSeqID = tmpBkReader.getSimpleText("REQ_SN");
                        tmpRetDetail.transState = "H+" + INFO_RET_CODE;

                        if (tmpBkRET_CODE != null && tmpBkRET_CODE.length() > 0) {
                            tmpRetDetail.transState += "+D+" + tmpBkRET_CODE;
                            tmpRetDetail.payInfoCode = tmpBkRET_CODE;
                            if ("3999".equals(tmpBkRET_CODE)) {
                                tmpRetDetail.payInfoCode = tmpBkERR_MSG;
                            }
                            tmpRetDetail.respInfo = tmpBkERR_MSG;
                        } else {
                            tmpRetDetail.payInfoCode = INFO_RET_CODE;
                            tmpRetDetail.respInfo = INFO_ERR_MSG;
                        }

                        tmpRetDetail.transAmt = p_req1908.singleDetail.payAmount;
                    } else {
                        tmpRetDetail.respCode = "-1";
                        tmpRetDetail.respInfo = "请求流水号" + tmpRetDetail.reqSeqID + "与响应" + tmpBkReader.getSimpleText("REQ_SN") + "不一致";
                    }
                } else {
                    tmpRetDetail.respCode = "-1";
                    tmpRetDetail.respInfo = tmpSbMsg.toString();
                }
            } else if (tmpStrRet[0].equals(ConnState.FAIL) || tmpStrRet[0].equals(FailCode.E9981)) {
                tmpRetDetail.respCode = "0";
                tmpRetDetail.respInfo = tmpStrRet[1];
                tmpRetDetail.reqSeqID = p_req1908.singleDetail.askNumber;
                tmpRetDetail.transState = PaymentState.FAIL_Batch;
                tmpRetDetail.payInfoCode = tmpStrRet[0];
            } else {
                tmpRetDetail.respCode = "-1";
                tmpRetDetail.respInfo = tmpStrRet[1];
            }
        } catch (Exception ex) {
            ex.printStackTrace();

            tmpRetDetail.respCode = "-1";
            tmpRetDetail.respInfo = ex.toString();

            WriteBankLogLn(ex);
        }

        return tmpRetDetail;
    }

    /**
     * 接口文档：https://jfb.allinpay.com/jfbgw/doc/toDoc.dsr#322
     *
     * @param p_req1908
     * @return
     * @throws Exception
     */
    private RetAtsSglDetail d_1908JFB(ReqSingle p_req1908) throws Exception {
        RetAtsSglDetail tmpRetDetail = new RetAtsSglDetail(p_req1908);

        try {
            ActSetItem actItem = getBankConfig().getActSetItem(p_req1908.singleDetail.payAct, "");
            if (actItem == null) {
                tmpRetDetail.respCode = "0";
                tmpRetDetail.respInfo = "未找到账号[" + p_req1908.singleDetail.payAct + "]商户配置信息";
                tmpRetDetail.transState = PaymentState.FAIL_Payment;
                tmpRetDetail.payInfoCode = FailCode.E9981;
                return tmpRetDetail;
            }

            AllInPay02Header header = new AllInPay02Header();
            header.TRX_CODE = "100014";
            header.REQ_SN = p_req1908.singleDetail.askNumber;

            XmlTextWriter xmlWriter = new XmlTextWriter();
            writeJFBCommonHeader(xmlWriter, header, actItem);

            xmlWriter.writeStartElement("BODY");
            XElement tmpXElement = new XElement("TRANS", "");
            String BUSINESS_CODE = this.getBankConfig().getMapValueBySrcXE("BUSINESS_CODE_1908", "srcCode", "desCode", p_req1908.singleDetail.srcXElement, p_req1908.singleDetail.useType);
            if (StringHelper.isNullOrEmpty(BUSINESS_CODE)) {
                BUSINESS_CODE = this.getBankConfig().getMapValueBySrcXE("BUSINESS_CODE_1988", "srcCode", "desCode", p_req1908.singleDetail.srcXElement, p_req1908.singleDetail.useType);
            }
            tmpXElement.addChild(new XElement("BUSINESS_CODE", BUSINESS_CODE));
            if (p_req1908.singleDetail.cardType.equals("1")) {
                tmpXElement.addChild(new XElement("ACCOUNT_TYPE", "01"));
            } else if (p_req1908.singleDetail.cardType.equals("3")) {
                tmpXElement.addChild(new XElement("ACCOUNT_TYPE", "02"));
            } else {
                tmpXElement.addChild(new XElement("ACCOUNT_TYPE", "00"));
            }
            if (p_req1908.singleDetail.isPrivate.equals("1")) {
                tmpXElement.addChild(new XElement("ACCOUNT_PROP", "0"));
            } else {
                tmpXElement.addChild(new XElement("ACCOUNT_PROP", "1"));
            }
            tmpXElement.addChild(new XElement("ACCOUNT_NO", p_req1908.singleDetail.recAct));
            tmpXElement.addChild(new XElement("ACCOUNT_NAME", p_req1908.singleDetail.recName));
            tmpXElement.addChild(new XElement("CVV2", ""));
            tmpXElement.addChild(new XElement("BANK_CODE", getBankConfig().getMapValueByKey("contractBankMapping", p_req1908.singleDetail.recBankCode)));
            tmpXElement.addChild(new XElement("BANK_NAME", p_req1908.singleDetail.cnapsName));
            if ("1".equals(p_req1908.singleDetail.isPrivate)) {
                tmpXElement.addChild(new XElement("UNION_BANK", ""));
            } else {
                tmpXElement.addChild(new XElement("UNION_BANK", p_req1908.singleDetail.cnapsCode));
            }
            tmpXElement.addChild(new XElement("PROVINCE", p_req1908.singleDetail.getOppProvinceAndCity()[0]));
            tmpXElement.addChild(new XElement("CITY", p_req1908.singleDetail.getOppProvinceAndCity()[1]));
            tmpXElement.addChild(new XElement("AMOUNT", StringHelper.amountMultiply100(p_req1908.singleDetail.payAmount)));
            tmpXElement.addChild(new XElement("CURRENCY", convertCurToBank(p_req1908.singleDetail.payCur)));
            String ID_TYPE = "";
            String ID = "";
            String ifNeed = getBankConfig().getMapValueByKey("needCertBank", p_req1908.singleDetail.payBankCode);
            if (ifNeed.toLowerCase().equals("true")) {
                String tmpMapped_ID_TYPE = this.convertCertTypeToBank(p_req1908.singleDetail.certType);
                if (StringHelper.hasAnyChar(tmpMapped_ID_TYPE) && StringHelper.hasAnyChar(p_req1908.singleDetail.certNum)) {
                    ID_TYPE = tmpMapped_ID_TYPE;
                    ID = p_req1908.singleDetail.certNum;
                }
            }
            tmpXElement.addChild(new XElement("ID_TYPE", ID_TYPE));
            tmpXElement.addChild(new XElement("ID", ID));
            tmpXElement.addChild(new XElement("TEL", p_req1908.singleDetail.cellPhone));
            tmpXElement.addChild(new XElement("CUST_USERID", p_req1908.singleDetail.askNumber));
            tmpXElement.addChild(new XElement("SUMMARY", p_req1908.singleDetail.purpose));
            tmpXElement.addChild(new XElement("REMARK", p_req1908.singleDetail.memo));
            this.nodeAnalysis(p_req1908.singleDetail.srcXElement, tmpXElement, this.getCharset());

            xmlWriter.writeXElement(tmpXElement);
            xmlWriter.writeEndDocument();

            String[] tmpStrRet = sendJFBToBank(xmlWriter.toXmlString(), actItem, header.REQ_SN);

            if (tmpStrRet[0].length() == 0) {
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
                if (tmpBkReader != null) {
                    String retCode = tmpBkReader.getFirstText("/AIPG/HEAD/RET_CODE");
                    String retMsg = tmpBkReader.getFirstText("/AIPG/HEAD/RET_MSG");

                    if (p_req1908.singleDetail.askNumber.equals(tmpBkReader.getSimpleText("REQ_SN"))) {
                        tmpRetDetail.respCode = "0";
                        tmpRetDetail.reqSeqID = tmpBkReader.getSimpleText("REQ_SN");
                        tmpRetDetail.transState = "JH+" + retCode;
                        tmpRetDetail.payInfoCode = retCode;
                        tmpRetDetail.respInfo = retMsg;
                        if ("3999".equals(retCode)) {
                            tmpRetDetail.payInfoCode = retMsg;
                        }
                        tmpRetDetail.transAmt = p_req1908.singleDetail.payAmount;
                    } else {
                        tmpRetDetail.respCode = "-1";
                        tmpRetDetail.respInfo = "请求流水号" + tmpRetDetail.reqSeqID + "与响应流水号" + tmpBkReader.getSimpleText("REQ_SN") + "不一致";
                    }
                } else {
                    tmpRetDetail.respCode = "-1";
                    tmpRetDetail.respInfo = tmpSbMsg.toString();
                }
            } else if (tmpStrRet[0].equals(ConnState.FAIL) || tmpStrRet[0].equals(FailCode.E9981)) {
                tmpRetDetail.respCode = "0";
                tmpRetDetail.respInfo = tmpStrRet[1];
                tmpRetDetail.reqSeqID = p_req1908.singleDetail.askNumber;
                tmpRetDetail.transState = PaymentState.FAIL_Batch;
                tmpRetDetail.payInfoCode = tmpStrRet[0];
            } else {
                tmpRetDetail.respCode = "-1";
                tmpRetDetail.respInfo = tmpStrRet[1];
            }
        } catch (Exception ex) {
            ex.printStackTrace();

            tmpRetDetail.respCode = "-1";
            tmpRetDetail.respInfo = ex.toString();

            WriteBankLogLn(ex);
        }

        return tmpRetDetail;
    }

    private RetAtsSglDetail d_190803(ReqSingle p_req1908) throws Exception {
        RetAtsSglDetail tmpRetDetail = new RetAtsSglDetail();

        try {
            ActSetItem actItem = getBankConfig().getActSetItem(p_req1908.singleDetail.payAct, "unionRecPay");
            if (actItem == null) {
                tmpRetDetail.respCode = "0";
                tmpRetDetail.respInfo = "未找到账号[" + p_req1908.singleDetail.payAct + "]批量商户配置信息";
                tmpRetDetail.reqSeqID = p_req1908.singleDetail.askNumber;
                tmpRetDetail.transState = PaymentState.FAIL_Payment;
                tmpRetDetail.payInfoCode = FailCode.E9981;
                return tmpRetDetail;
            }

            AllInPay02Header header = new AllInPay02Header();
            header.TRX_CODE = "300003";
            header.REQ_SN = p_req1908.singleDetail.askNumber;

            XmlTextWriter xmlWriter = new XmlTextWriter();
            writeAgrmCommonHeader(xmlWriter, header, actItem);

            XElement tmpXElement = new XElement("CASHREQ", "");
            tmpXElement.addChild(new XElement("ACCTNO", actItem.inMerchantId));
            tmpXElement.addChild(new XElement("BANKACCT", p_req1908.singleDetail.recAct));
            tmpXElement.addChild(new XElement("AMOUNT", StringHelper.amountMultiply100(p_req1908.singleDetail.payAmount)));
            tmpXElement.addChild(new XElement("USAGE", p_req1908.singleDetail.description));
            tmpXElement.addChild(new XElement("CUST_USERID", p_req1908.singleDetail.userId));
            tmpXElement.addChild(new XElement("MEMO", p_req1908.singleDetail.memo));
            this.nodeAnalysis(p_req1908.singleDetail.srcXElement, tmpXElement, this.getCharset());
            xmlWriter.writeXElement(tmpXElement);
            xmlWriter.writeEndDocument();

            String[] tmpStrRet = sendToBank(xmlWriter.toXmlString(), actItem);

            if (tmpStrRet[0].length() == 0) {
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
                if (tmpBkReader != null) {
                    String INFO_RET_CODE = tmpBkReader.getFirstText("/AIPG/INFO/RET_CODE");
                    String INFO_ERR_MSG = tmpBkReader.getFirstText("/AIPG/INFO/ERR_MSG");

                    if (p_req1908.singleDetail.askNumber.equals(tmpBkReader.getSimpleText("REQ_SN"))) {
                        tmpRetDetail.respCode = "0";
                        tmpRetDetail.reqSeqID = tmpBkReader.getSimpleText("REQ_SN");
                        tmpRetDetail.transState = "H+" + INFO_RET_CODE;

                        if (INFO_RET_CODE != null && INFO_RET_CODE.length() > 0) {
                            tmpRetDetail.transState += "+D+" + INFO_RET_CODE;
                            tmpRetDetail.payInfoCode = INFO_RET_CODE;
                            if ("3999".equals(INFO_RET_CODE)) {
                                tmpRetDetail.payInfoCode = INFO_ERR_MSG;
                            }
                            tmpRetDetail.respInfo = INFO_ERR_MSG;
                        } else {
                            tmpRetDetail.payInfoCode = INFO_RET_CODE;
                            tmpRetDetail.respInfo = INFO_ERR_MSG;
                        }

                        tmpRetDetail.transAmt = p_req1908.singleDetail.payAmount;
                    } else {
                        tmpRetDetail.respCode = "-1";
                        tmpRetDetail.respInfo = "请求流水号" + tmpRetDetail.reqSeqID + "与响应" + tmpBkReader.getSimpleText("REQ_SN") + "不一致";
                    }
                } else {
                    tmpRetDetail.respCode = "-1";
                    tmpRetDetail.respInfo = tmpSbMsg.toString();
                }
            } else if (tmpStrRet[0].equals(ConnState.FAIL) || tmpStrRet[0].equals(FailCode.E9981)) {
                tmpRetDetail.respCode = "0";
                tmpRetDetail.respInfo = tmpStrRet[1];
                tmpRetDetail.reqSeqID = p_req1908.singleDetail.askNumber;
                tmpRetDetail.transState = PaymentState.FAIL_Payment;
                tmpRetDetail.payInfoCode = tmpStrRet[0];
            } else {
                tmpRetDetail.respCode = "-1";
                tmpRetDetail.respInfo = tmpStrRet[1];
            }
        } catch (Exception ex) {
            ex.printStackTrace();

            tmpRetDetail.respCode = "-1";
            tmpRetDetail.respInfo = ex.toString();

            WriteBankLogLn(ex);
        }

        return tmpRetDetail;
    }

    private RetAtsSglDetail d_690803(ReqSingle p_req1908) throws Exception {
        RetAtsSglDetail tmpRetDetail = new RetAtsSglDetail(p_req1908);
        try {
            ActSetItem actItem = getBankConfig().getActSetItem(p_req1908.singleDetail.payAct, "unifiedorder");
            if (actItem == null) {
                tmpRetDetail.respCode = "0";
                tmpRetDetail.respInfo = "未找到账号[" + p_req1908.singleDetail.payAct + "]商户配置信息";
                tmpRetDetail.transState = PaymentState.FAIL_Payment;
                tmpRetDetail.payInfoCode = FailCode.E9981;
                return tmpRetDetail;
            }

            TreeMap<String, String> params = new TreeMap<String, String>();

            params.put("cusid", actItem.merchantId);
            params.put("appid", actItem.appId);
            params.put("version", "11");
            params.put("randomstr", get_nonce_str());
            params.put("payercusid", p_req1908.singleDetail.payAct);
            params.put("payeecusid", p_req1908.singleDetail.recAct);
            params.put("trxamt", StringHelper.amountMultiply100(p_req1908.singleDetail.payAmount));
            params.put("reqsn", p_req1908.singleDetail.askNumber);
            params.put("remark", p_req1908.singleDetail.memo);
            params.put("sign", SybUtil.sign(params, actItem.saltKey));

            String tmpRetStr = sendUnifiedToBank(params, bankFront.getUrl("submitTransferBal"));

            if (StringHelper.hasAnyChar(tmpRetStr)) {
                if (tmpRetStr.indexOf("{") >= 0) {
                    JSONObject respJson = JSONObject.parseObject(tmpRetStr);

                    String respCode = respJson.getString("retcode");
                    if (respCode.equals("SUCCESS")) {
                        tmpRetDetail.respCode = "0";
                        tmpRetDetail.respInfo = respJson.getString("errmsg");
                        String transState = respJson.getString("trxstatus");
                        if ("0000".equals(transState)) {
                            tmpRetDetail.transState = "2";
                        } else if ("2008".equals(transState) || "2000".equals(transState)) {
                            tmpRetDetail.transState = "4";
                        } else {
                            if (transState.startsWith("3")) {
                                tmpRetDetail.transState = "3";
                            } else {
                                tmpRetDetail.respCode = "-1";
                                tmpRetDetail.transState = transState;
                            }
                        }
                    } else {
                        tmpRetDetail.respCode = "-1";
                        tmpRetDetail.respInfo = respJson.getString("retmsg");
                    }
                } else {
                    tmpRetDetail.respCode = "-1";
                    tmpRetDetail.respInfo = tmpRetStr;
                }
            } else {
                tmpRetDetail.respCode = "-1";
                tmpRetDetail.respInfo = "通联响应数据为空";
            }

        } catch (Exception ex) {
            ex.printStackTrace();
            tmpRetDetail.respCode = "-1";
            tmpRetDetail.respInfo = ex.getMessage();
            WriteBankLogLn(ex);
        }

        return tmpRetDetail;
    }

    @Override
    public RetAtsSingleBat d_1908BAT_SglBatPay(ReqSingleBat p_req1908BAT) throws Exception {
        return null;
    }


    public RetAtsSingle d_1944_QrySglPay(ReqQrySingle p_req1944) throws Exception {
        if ("690803".equals(p_req1944.reqHeader.commandCode)) {
            return d_6944(p_req1944);
        } else if ("1908JFB".equals(p_req1944.reqHeader.commandCode)) {
            return d_1944_1908JFB(p_req1944);
        } else {
            return d_1944_QryOrdinarySglPay(p_req1944);
        }
    }

    public RetAtsSingle d_1944_QryOrdinarySglPay(ReqQrySingle p_req1944) throws Exception {
        RetAtsSingle retAts = new RetAtsSingle(p_req1944.reqHeader);
        RetAtsSglDetail tmpRetDetail = new RetAtsSglDetail();

        try {
            ActSetItem actItem = getBankConfig().getActSetItem(p_req1944.payAct, "");
            if (actItem == null) {
                tmpRetDetail.respCode = "-1";
                tmpRetDetail.respInfo = "未找到账号" + p_req1944.payAct + "对应的商户配置信息";
                //tmpRetDetail.reqSeqID = p_req1944.askNumber;
                //tmpRetDetail.transAmt = p_req1944.payAmount;
                //tmpRetDetail.transState = PaymentState.FAIL_Payment;
                //tmpRetDetail.payInfoCode = FailCode.E9981;

                retAts.writeRetDetail(tmpRetDetail);
                return retAts;
            }

            AllInPay02Header bankHeader = new AllInPay02Header();
            bankHeader.REQ_SN = getQryTransID();
            bankHeader.TRX_CODE = "200004";

            XmlTextWriter xmlWriter = new XmlTextWriter();
            writeRealTimeCommonHeader(xmlWriter, bankHeader, actItem);

            xmlWriter.writeStartElement("QTRANSREQ");
            xmlWriter.writeElementString("MERCHANT_ID", actItem.merchantId);
            xmlWriter.writeElementString("QUERY_SN", p_req1944.askNumber);
            xmlWriter.writeElementString("STATUS", "2");
            xmlWriter.writeElementString("TYPE", "1");
            xmlWriter.writeElementClosed("START_DAY");
            xmlWriter.writeElementClosed("END_DAY");
            xmlWriter.writeEndDocument();

            String[] tmpStrRet = sendToBank(xmlWriter.toXmlString(), actItem);
            //tmpStrRet[0]="";
            //tmpStrRet[1]=FileHelper.readFileText("D:\\getToWork\\14-filesForDevelop\\AllInPay02\\新建文本文档.txt", "gbk");

            if (tmpStrRet[0].length() == 0) {
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
                if (tmpBkReader != null) {
                    tmpRetDetail.respCode = "";
                    String INFO_RET_CODE = tmpBkReader.getFirstText("/AIPG/INFO/RET_CODE");
                    String INFO_ERR_MSG = tmpBkReader.getFirstText("/AIPG/INFO/ERR_MSG");
                    if ("0000".equals(INFO_RET_CODE) || "0001".equals(INFO_RET_CODE) || "0002".equals(INFO_RET_CODE) || "1002".equals(INFO_RET_CODE) || "1999".equals(INFO_RET_CODE) || "2000".equals(INFO_RET_CODE) || "2001".equals(INFO_RET_CODE) || "2002".equals(INFO_RET_CODE) || "2003".equals(INFO_RET_CODE) || "2004".equals(INFO_RET_CODE) || "2005".equals(INFO_RET_CODE) || "2006".equals(INFO_RET_CODE) || "2007".equals(INFO_RET_CODE) || "2008".equals(INFO_RET_CODE)) {
                        String bkBATCHID = tmpBkReader.getFirstText("/AIPG/QTRANSRSP/QTDETAIL/BATCHID");
                        String bkRET_CODE = tmpBkReader.getFirstText("/AIPG/QTRANSRSP/QTDETAIL/RET_CODE");
                        String bkERR_MSG = tmpBkReader.getFirstText("/AIPG/QTRANSRSP/QTDETAIL/ERR_MSG");

                        if (bkBATCHID != null && bkBATCHID.length() > 0 && !p_req1944.askNumber.equals(bkBATCHID)) {
                            tmpRetDetail.respCode = "-1";
                            tmpRetDetail.respInfo = "请求流水号" + p_req1944.askNumber + "与响应" + bkBATCHID + "不一致";
                        } else if (tmpStrRet[1].indexOf("QTDETAIL") < 0) {
                            tmpRetDetail.respCode = "0";
                            tmpRetDetail.reqSeqID = p_req1944.askNumber;
                            tmpRetDetail.transState = "H+" + INFO_RET_CODE;

                            if (bkRET_CODE != null && bkRET_CODE.length() > 0) {
                                tmpRetDetail.transState += "+D+" + bkRET_CODE;
                                tmpRetDetail.payInfoCode = bkRET_CODE;
                                if ("3999".equals(bkRET_CODE)) {
                                    tmpRetDetail.payInfoCode = bkERR_MSG;
                                }
                                tmpRetDetail.respInfo = bkERR_MSG;
                            } else {
                                tmpRetDetail.payInfoCode = INFO_RET_CODE;
                                tmpRetDetail.respInfo = INFO_ERR_MSG;
                            }
                        } else {
                            if (!"-1".equals(tmpRetDetail.respCode)) {
                                tmpRetDetail.respCode = "0";
                                tmpRetDetail.reqSeqID = p_req1944.askNumber;
                                tmpRetDetail.transState = "H+" + INFO_RET_CODE;

                                if (bkRET_CODE != null && bkRET_CODE.length() > 0) {
                                    tmpRetDetail.transState += "+D+" + bkRET_CODE;
                                    tmpRetDetail.payInfoCode = bkRET_CODE;
                                    if ("3999".equals(bkRET_CODE)) {
                                        tmpRetDetail.payInfoCode = bkERR_MSG;
                                    }
                                    tmpRetDetail.respInfo = bkERR_MSG;
                                } else {
                                    tmpRetDetail.payInfoCode = INFO_RET_CODE;
                                    tmpRetDetail.respInfo = INFO_ERR_MSG;
                                }

                                String bkAMOUNT = tmpBkReader.getFirstText("/AIPG/QTRANSRSP/QTDETAIL/AMOUNT");
                                if (bkAMOUNT != null && bkAMOUNT.length() > 0) {
                                    tmpRetDetail.transAmt = StringHelper.amountDivide100(bkAMOUNT);
                                }
                            }
                        }

                        if ("1002".equals(INFO_RET_CODE)) {
                            if (tmpStrRet[1].indexOf("QTDETAIL") >= 0) {
                                tmpRetDetail.respCode = "-1";
                                tmpRetDetail.respInfo = "RET_CODE为1002但QTDETAIL节点非空";
                            } else {
                                this.canBeNotExist(p_req1944, tmpRetDetail, 10);
                            }
                        }
                    } else {
                        tmpRetDetail.respCode = "-1";
                        tmpRetDetail.respInfo = INFO_RET_CODE + "-" + INFO_ERR_MSG;
                    }
                } else {
                    tmpRetDetail.respCode = "-1";
                    tmpRetDetail.respInfo = tmpSbMsg.toString();
                }
            } else {
                tmpRetDetail.respCode = "-1";
                tmpRetDetail.respInfo = tmpStrRet[1];
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            tmpRetDetail.respCode = "-1";
            tmpRetDetail.respInfo = ex.getMessage();
            WriteBankLogLn(ex);
        }

        if (tmpRetDetail.respCode.equals("-1") && StringHelper.isNullOrEmpty(tmpRetDetail.reqSeqID)) {
            tmpRetDetail.reqSeqID = p_req1944.askNumber;
        }

        retAts.writeRetDetail(tmpRetDetail);
        return retAts;
    }

    public RetAtsSingle d_1944_1908JFB(ReqQrySingle p_req1944) throws Exception {
        RetAtsSingle retAts = new RetAtsSingle(p_req1944.reqHeader);
        RetAtsSglDetail tmpRetDetail = new RetAtsSglDetail(p_req1944);

        try {
            ActSetItem actItem = getBankConfig().getActSetItem(p_req1944.payAct, "");
            if (actItem == null) {
                tmpRetDetail.respCode = "-1";
                tmpRetDetail.respInfo = "未找到账号" + p_req1944.payAct + "对应的商户配置信息";
                retAts.writeRetDetail(tmpRetDetail);
                return retAts;
            }

            AllInPay02Header bankHeader = new AllInPay02Header();
            bankHeader.REQ_SN = p_req1944.askNumber;
            bankHeader.TRX_CODE = "200004";

            XmlTextWriter xmlWriter = new XmlTextWriter();
            writeJFBCommonHeader(xmlWriter, bankHeader, actItem);

            xmlWriter.writeStartElement("BODY");
            xmlWriter.writeStartElement("QTRANSREQ");
            xmlWriter.writeElementString("SRC_BATCHID", p_req1944.askNumber);
            xmlWriter.writeElementString("SRC_SN", "");
            xmlWriter.writeEndDocument();

            String[] tmpStrRet = sendJFBToBank(xmlWriter.toXmlString(), actItem, bankHeader.REQ_SN);

            if (tmpStrRet[0].length() == 0) {
                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpStrRet[1], tmpSbMsg);
                if (tmpBkReader != null) {
                    String INFO_RET_CODE = tmpBkReader.getFirstText("/AIPG/HEAD/RET_CODE");
                    String INFO_ERR_MSG = tmpBkReader.getFirstText("/AIPG/HEAD/ERR_MSG");
                    if ("0000".equals(INFO_RET_CODE)) {
                        String bkBATCHID = tmpBkReader.getFirstText("/AIPG/BODY/QTDETAILS/QTDETAIL/BATCHID");
                        String bkRET_CODE = tmpBkReader.getFirstText("/AIPG/BODY/QTDETAILS/QTDETAIL/RESULT_CODE");
                        String bkERR_MSG = tmpBkReader.getFirstText("/AIPG/BODY/QTDETAILS/QTDETAIL/RESULT_MSG");
                        if (bkBATCHID != null && bkBATCHID.length() > 0 && !p_req1944.askNumber.equals(bkBATCHID)) {
                            tmpRetDetail.respCode = "-1";
                            tmpRetDetail.respInfo = "请求流水号" + p_req1944.askNumber + "与响应流水号" + bkBATCHID + "不一致";
                            retAts.writeRetDetail(tmpRetDetail);
                            return retAts;
                        }
                        if (StringHelper.hasAnyChar(bkRET_CODE)) {
                            tmpRetDetail.respCode = "0";
                            tmpRetDetail.transState = "JH+" + INFO_RET_CODE + "+JD+" + bkRET_CODE;
                            tmpRetDetail.payInfoCode = bkRET_CODE;
                            if ("3999".equals(bkRET_CODE)) {
                                tmpRetDetail.payInfoCode = bkERR_MSG;
                            }
                            tmpRetDetail.respInfo = bkERR_MSG;
                        } else {
                            tmpRetDetail.payInfoCode = "-1";
                            tmpRetDetail.respInfo = "通联金服宝响应报文/AIPG/BODY/QTDETAILS/QTDETAIL/RESULT_CODE节点为空，处理中，请稍后查询！";
                        }
                    } else if ("1002".equals(INFO_RET_CODE)) {
                        if (canBeNotExist(p_req1944, tmpRetDetail, 50)) {
                            tmpRetDetail.respCode = "0";
                            tmpRetDetail.reqSeqID = p_req1944.askNumber;
                            tmpRetDetail.transState = "JH+" + INFO_RET_CODE;
                            tmpRetDetail.payInfoCode = INFO_RET_CODE;
                            tmpRetDetail.respInfo = INFO_ERR_MSG;
                            tmpRetDetail.transAmt = p_req1944.payAmount;
                        }
                    } else {
                        tmpRetDetail.respCode = "-1";
                        tmpRetDetail.respInfo = INFO_RET_CODE + "-" + INFO_ERR_MSG;
                    }
                } else {
                    tmpRetDetail.respCode = "-1";
                    tmpRetDetail.respInfo = tmpSbMsg.toString();
                }
            } else {
                tmpRetDetail.respCode = "-1";
                tmpRetDetail.respInfo = tmpStrRet[1];
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            tmpRetDetail.respCode = "-1";
            tmpRetDetail.respInfo = ex.getMessage();
            WriteBankLogLn(ex);
        }

        if (tmpRetDetail.respCode.equals("-1") && StringHelper.isNullOrEmpty(tmpRetDetail.reqSeqID)) {
            tmpRetDetail.reqSeqID = p_req1944.askNumber;
        }

        retAts.writeRetDetail(tmpRetDetail);
        return retAts;
    }

    private RetAtsSingle d_6944(ReqQrySingle p_req1944) throws Exception {
        RetAtsSingle retAts = new RetAtsSingle(p_req1944.reqHeader);
        RetAtsSglDetail tmpRetDetail = new RetAtsSglDetail(p_req1944);

        try {
            ActSetItem actItem = getBankConfig().getActSetItem(p_req1944.payAct, "unifiedorder");
            if (actItem == null) {
                tmpRetDetail.respCode = "-1";
                tmpRetDetail.respInfo = "未找到账号" + p_req1944.payAct + "对应的商户配置信息";
                retAts.writeRetDetail(tmpRetDetail);
                return retAts;
            }

            TreeMap<String, String> params = new TreeMap<String, String>();

            params.put("cusid", actItem.merchantId);
            params.put("appid", actItem.appId);
            params.put("version", "11");
            params.put("randomstr", get_nonce_str());
            params.put("trxtype", "01");
            params.put("reqsn", p_req1944.askNumber);
            params.put("trxid", "");
            params.put("sign", SybUtil.sign(params, actItem.saltKey));

            String tmpRetStr = sendUnifiedToBank(params, bankFront.getUrl("queryTransferBal"));

            if (StringHelper.hasAnyChar(tmpRetStr)) {
                if (tmpRetStr.indexOf("{") >= 0) {
                    JSONObject respJson = JSONObject.parseObject(tmpRetStr);
                    String respCode = respJson.getString("retcode");
                    if (respCode.equals("SUCCESS")) {
                        tmpRetDetail.respCode = "0";
                        String errMsg = respJson.getString("errmsg");
                        if (StringHelper.isNullOrEmpty(errMsg)) {
                            tmpRetDetail.respInfo = respJson.getString("retmsg");
                        } else {
                            tmpRetDetail.respInfo = errMsg;
                        }
                        String status = respJson.getString("trxstatus");
                        if("0000".equals(status)){
                            tmpRetDetail.transState = "2";
                        }else if("2008".equals(status)){
                            tmpRetDetail.transState = "4";
                        }else{
                            if (status.startsWith("3")) {
                                tmpRetDetail.transState = "3";
                            } else {
                                tmpRetDetail.respCode = "-1";
                                tmpRetDetail.transState = status;
                            }
                        }
                    } else {
                        tmpRetDetail.respCode = "-1";
                        tmpRetDetail.respInfo = respJson.getString("retmsg");
                    }
                } else {
                    tmpRetDetail.respCode = "-1";
                    tmpRetDetail.respInfo = tmpRetStr;
                }
            } else {
                tmpRetDetail.respCode = "-1";
                tmpRetDetail.respInfo = "通联响应数据为空";
            }

        } catch (Exception ex) {
            ex.printStackTrace();
            tmpRetDetail.respCode = "-1";
            tmpRetDetail.respInfo = ex.getMessage();
            WriteBankLogLn(ex);
        }
        retAts.writeRetDetail(tmpRetDetail);
        return retAts;
    }

    @Override
    public RetAtsSingleBat d_1944BAT_QrySglBatPay(ReqQrySingleBat p_req1944BAT) throws Exception {
        return null;
    }
}
